/*
 * @Author: yuta
 * @Date: 2021-09-10 15:05:17
 * @LastEditTime: 2021-09-10 15:05:18
 * @LastEditors: yuta
 */
/*
 * @Author: Drc
 * @Date: 2021-07-12 16:24:25
 * @LastEditTime: 2021-07-19 14:44:54
 * @LastEditors: Drc
 */

import React, {Component, useEffect, useRef, useState} from 'react'
import {TouchableOpacity, View, Animated, ViewStyle, Easing} from 'react-native'
import LinearGradient from 'react-native-linear-gradient'
import Theme from '@path/config/theme'
import System, {px2dp} from '@path/config/system'

interface SwitchProps {
  status: boolean
  disabled: boolean
  onStatusChanged: (status: boolean) => any
  style?: ViewStyle
}

class GradientHelper extends Component {
  render() {
    const {style, color1, color2, start = {x: 0, y: 0}, end = {x: 0, y: 1}} = this.props
    return <LinearGradient colors={[color1, color2]} start={start} end={end} style={style} />
  }
}

const AnimatedLinearGradient = Animated.createAnimatedComponent(GradientHelper)

const Switch = (props: SwitchProps) => {
  //配置
  const width = px2dp(47)
  const height = px2dp(24)
  const paddingH = px2dp(3)
  const thumbSize = px2dp(18)
  const bgColor = {
    on: '#9C72F7',
    off: Theme.currentTheme === 'dark' ? '#444278' : '#E9E9E9',
  }
  const thumbColor = {
    on: ['#FFFFFF', '#B499FC'],
    off: Theme.currentTheme === 'dark' ? ['#B592FF', '#7452BF'] : ['#C2A5FF', '#9C72F7'],
  }

  //动画
  const isAnimated = useRef(false)
  const statusAnim = useRef(new Animated.Value(0))
  const bgColorAnim = statusAnim.current?.interpolate({
    inputRange: [0, 1],
    outputRange: [bgColor.off, bgColor.on],
  })
  const thumbLeftAnim = statusAnim.current?.interpolate({
    inputRange: [0, 1],
    outputRange: [0, width - paddingH * 2 - thumbSize],
  })
  const thumbColorAnim1 = statusAnim.current?.interpolate({
    inputRange: [0, 1],
    outputRange: [thumbColor.off[0], thumbColor.on[0]],
  })

  const thumbColorAnim2 = statusAnim.current?.interpolate({
    inputRange: [0, 1],
    outputRange: [thumbColor.off[1], thumbColor.on[1]],
  })

  useEffect(() => {
    startAnim(props.status)
  }, [props.status])

  const startAnim = (toStatus: boolean) => {
    if (isAnimated.current) {
      return
    }
    isAnimated.current = true

    if (toStatus) {
      Animated.timing(statusAnim.current, {
        toValue: 1,
        duration: 150,
        easing: Easing.linear,
        useNativeDriver: false,
      }).start(() => {
        isAnimated.current = false
      })
    } else {
      Animated.timing(statusAnim.current, {
        toValue: 0,
        duration: 150,
        easing: Easing.linear,
        useNativeDriver: false,
      }).start(() => {
        isAnimated.current = false
      })
    }
  }

  return (
    <TouchableOpacity
      activeOpacity={1}
      disabled={props.disabled}
      style={props.style}
      onPress={() => {
        props.onStatusChanged(!props.status)
      }}>
      <Animated.View
        style={{
          paddingHorizontal: paddingH,
          width,
          height,
          borderRadius: px2dp(12),
          justifyContent: 'center',
          backgroundColor: bgColorAnim,
          opacity: props.disabled ? 0.5 : 1,
        }}>
        <Animated.View
          style={{
            marginLeft: thumbLeftAnim,
            width: thumbSize,
            height: thumbSize,
            shadowOffset: {width: 0, height: 3},
            shadowColor: '#50009F',
            shadowOpacity: props.status ? 0.26 : 0,
            shadowRadius: 6,
          }}>
          <AnimatedLinearGradient
            style={{
              width: thumbSize,
              height: thumbSize,
              borderRadius: px2dp(9),
            }}
            start={{x: 0, y: 0}}
            end={{x: 0, y: 1}}
            color1={thumbColorAnim1}
            color2={thumbColorAnim2}
            // colors={[thumbColorAnim1, thumbColorAnim2]}
            // colors={thumbColor[props.status ? 'on' : 'off']}
          />
        </Animated.View>
      </Animated.View>
    </TouchableOpacity>
  )
}

export default Switch
